<template>
  <div class="loadmore"
       @touchstart="touchstart"
       @touchmove="touchmove"
       @touchend="touchend">
    <div class="loadmore-content">
      <slot name="loadmoreContent"></slot>
    </div>
    <div class="top-pull">
      <slot name="topPull"
            v-if="topType==0">{{topPullText}}</slot>
      <slot name="topDrop"
            v-else-if="topType==1">{{topDropText}}</slot>
      <slot name="topLoading"
            v-else-if="topType==2">{{topLoadingText}}</slot>
      <slot name="topNodata"
            v-else-if="topType==3">{{topNodataText}}</slot>
    </div>
    <div class="bottom-pull">
      <slot name="bottomPull"
            v-if="bottomType==0">{{bottomPullText}}</slot>
      <slot name="bottomDrop"
            v-else-if="bottomType==1">{{bottomDropText}}</slot>
      <slot name="bottomLoading"
            v-else-if="bottomType==2">{{bottomLoadingText}}</slot>
      <slot name="bottomNodata"
            v-else-if="bottomType==3">{{bottomNodataText}}</slot>
    </div>
  </div>
</template>
<script>
export default {
	props : {
		auto : { // 是否初始化调用一次下拉加载
			type : Boolean,
			default : true
		},
		topDistance : { // 下拉加载的触发的距离
			type : Number,
			default : 50
		},
		bottomDistance : { // 上拉加载的触发的距离
			type : Number,
			default : 50
		},
		distanceIndex : { // 手指移动与组件移动距离的比值
			type : Number,
			default : 3
		},
		isLock : { // 是否锁定下拉上拉
			type : Boolean,
			default : false
		},
		isDown : { // 是否有下拉加载
			type : Boolean,
			default : true
		},
		isUp : { // 是否有上拉加载
			type : Boolean,
			default : true
		},
		topPullText : {
			type : String,
			default : '下拉刷新'
		},
		topDropText : {
			type : String,
			default : '释放更新'
		},
		topLoadingText : {
			type : String,
			default : '加载中...'
		},
		topNodataText : {
			type : String,
			default : '没有数据'
		},
		bottomPullText : {
			type : String,
			default : '上拉加载'
		},
		bottomDropText : {
			type : String,
			default : '释放更新'
		},
		bottomLoadingText : {
			type : String,
			default : '加载中...'
		},
		bottomNodataText : {
			type : String,
			default : '没有更多数据了...'
		}
	},
	data () {
		return {
			privateTopDistance : this.topDistance * this.distanceIndex,
			privateIsDown : this.isDown,
			privateIsUp : this.isUp,
			topType : -1,
			bottomType : -1,
			loadmoreContent : null,
			loadmoreHeight : 0,
			bottomPullHeight : 0,
			topPullHeight : 0,
			lock : false,
			direction : '',
			domCurrentX : '',
			domCurrentY : '',
			startY : 0,
			Y : 0
		};
	},
	mounted () {
		this.loadmoreContent = document.querySelector('.loadmore-content');
		this.loadmoreHeight = document.querySelector('.loadmore').offsetHeight;
		this.bottomPullHeight = document.querySelector('.bottom-pull').offsetHeight;
		this.topPullHeight = document.querySelector('.top-pull').offsetHeight;
		this.lock = true;
		if (this.privateIsDown && this.auto) {
			this.topType = 2;
			this.Y = this.topPullHeight * this.distanceIndex;
			this.loadmoreContent.style.transition = '0.3s all ease';
			this.loadmoreContent.style.transform = `translateY(${this.topPullHeight}px)`;
			this.$emit('topMethod');
		}
	},
	methods : {
		touchstart (e) {
			if (this.lock) return;
			this.direction = '';
			this.domCurrentX = e.targetTouches[0].pageX;
			this.domCurrentY = e.targetTouches[0].pageY;
			this.startY = e.targetTouches[0].pageY - this.Y;
			this.loadmoreContent.style.transition = 'none';
		},
		touchmove (e) {
			if (this.lock) return;
			if (this.direction === '') {
				if (Math.abs(e.targetTouches[0].pageX - this.domCurrentX) > 5) {
					this.direction = 'x';
				} else if (Math.abs(e.targetTouches[0].pageY - this.domCurrentY) > 5) {
					this.direction = 'y';
				}

			} else {
				if (this.direction === 'y') {
					this.Y = e.targetTouches[0].pageY - this.startY;
					if (this.privateIsDown && this.Y > 0) {
						if (this.Y >= this.privateTopDistance) {
							this.topType = 1;
							if (this.isLock) return;
						} else {
							this.topType = 0;
						}
						this.loadmoreContent.style.transform = `translateY(${this.Y / this.distanceIndex}px)`;
						this.$emit('setYdistance', this.Y / this.distanceIndex);
					} else if (this.privateIsUp && this.Y < 0) {
						if (-this.Y - (this.loadmoreContent.offsetHeight - this.loadmoreHeight) >= this.bottomDistance) {
							this.bottomType = 1;
							if (this.isLock) return;
						} else {
							this.bottomType = 0;
						}
						this.loadmoreContent.style.transform = `translateY(${this.Y}px)`;
						this.$emit('setYdistance', this.Y);
					} else if (!this.privateIsUp) {
						// 边界
						let bounds = this.loadmoreContent.offsetHeight - this.loadmoreHeight;
						if (bounds > 0) {
							this.loadmoreContent.style.transform = `translateY(${this.Y}px)`;
						} else {
							this.Y = 0;
						}
					}

				}
			}
		},
		touchend () {
			if (this.lock) return;
			if (this.privateIsDown && this.Y > 0) {
				this.loadmoreContent.style.transition = '0.3s all ease';
				if (this.topType === 1) {
					this.lock = true;
					this.topType = 2;
					this.Y = this.topPullHeight * this.distanceIndex;
					this.$emit('topMethod');
					this.loadmoreContent.style.transform = `translateY(${this.topPullHeight}px)`;
				} else {
					this.Y = 0;
					this.loadmoreContent.style.transform = 'translateY(0px)';
				}
			} else if (this.privateIsUp && this.Y < 0) {
				if (this.bottomType === 1) {
					this.loadmoreContent.style.transition = '0.3s all ease';
					if (!this.isLock) {
						this.Y = -(this.loadmoreContent.offsetHeight - this.loadmoreHeight + this.bottomPullHeight);
						this.loadmoreContent.style.transform = `translateY(${-(this.loadmoreContent.offsetHeight - this.loadmoreHeight + this.bottomPullHeight)}px)`;
					}
					this.lock = true;
					this.bottomType = 2;
					this.$emit('bottomMethod');
				} else {
					let bottomDistance = -this.Y - (this.loadmoreContent.offsetHeight - this.loadmoreHeight);
					if (bottomDistance > 0 && bottomDistance < this.bottomDistance) {
						this.Y = -(this.loadmoreContent.offsetHeight - this.loadmoreHeight);
						this.loadmoreContent.style.transition = '0.3s all ease';
						this.loadmoreContent.style.transform = `translateY(${this.Y}px)`;
					}
				}
			} else if (!this.privateIsUp) {
				// 边界
				let bounds = this.loadmoreContent.offsetHeight - this.loadmoreHeight;
				if (bounds > 0 && (this.Y + bounds) <= 0) {
					this.Y = -(this.loadmoreContent.offsetHeight - this.loadmoreHeight + this.bottomPullHeight);
					this.loadmoreContent.style.transition = '0.3s all ease';
					this.loadmoreContent.style.transform = `translateY(${this.Y}px)`;
				}
			}
		},
		loadmoreEnd (noData = false) {
			this.lock = false;
			if (this.topType === 2) {
				if (noData) {
					this.privateIsUp = false;
					this.topType = 3;
					this.bottomType = 3;
				} else {
					this.topType = 0;
					setTimeout(() => {
						if (this.loadmoreContent.offsetHeight - this.loadmoreHeight < 0) {
							this.lock = true;
							this.privateIsUp = false;
							this.bottomType = 2;
							this.$emit('bottomMethod');
						}
					}, 30);
				}
				this.Y = 0;
				this.loadmoreContent.style.transform = 'translateY(0px)';
			} else if (this.bottomType === 2) {
				if (noData) {
					this.privateIsUp = false;
					this.bottomType = 3;
				} else {
					setTimeout(() => {
						if (this.loadmoreContent.offsetHeight - this.loadmoreHeight < 0) {
							this.lock = true;
							this.privateIsUp = false;
							this.bottomType = 2;
							this.$emit('bottomMethod');
						} else {
							this.privateIsUp = true;
							this.bottomType = 0;
						}
					}, 30);

				}
			}
		}
	}
};
</script>
<style lang="scss" scoped>
.loadmore {
  width: 100%;
  height: 800px;
  position: relative;
  overflow: hidden;
  border: 1px solid #000;
}
.loadmore-content {
  background: #fff;
  position: relative;
  z-index: 1;
}
.top-pull {
  height: 40px;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
}
.bottom-pull {
  height: 40px;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
}
</style>
